package fr.ysa.services;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;

import fr.ysa.persistence.DaoException;
import fr.ysa.persistence.Entity;
import fr.ysa.persistence.IDao;
import fr.ysa.persistence.requetes.ConfigRequetes;
import fr.ysa.services.config.ConfigRequetesDto;
import fr.ysa.services.config.ConfigRequetesTransform;

public abstract class ImplService<U extends Entity, T extends EntityDto>
		implements IService<T> {

	@Autowired
	Mapper mapper;

	@Autowired
	ConfigRequetesTransform transformConfigRequetes;

	public abstract Class<U> getEntityClass();

	public abstract Class<T> getEntityDtoClass();

	public abstract IDao<U> getDao();

	@Override
	public T sauvegarder(T obj) throws ServiceException {
		try {
			U entity = getDao().sauvegarder(mapper.map(obj, getEntityClass()));
			return mapper.map(entity, getEntityDtoClass());
		} catch (DaoException e) {
			throw new ServiceException(e.getMessage());
		}
	}

	@Override
	public Collection<T> sauvegarder(Collection<T> entities)
			throws ServiceException {
		try {

			List<U> listServer = new ArrayList<U>();
			for (T entity : entities) {
				listServer.add(mapper.map(entity, getEntityClass()));
			}
			getDao().sauvegarder(listServer);
			entities.clear();
			for (U entity : listServer) {
				entities.add(mapper.map(entity, getEntityDtoClass()));
			}
			return entities;
		} catch (DaoException e) {
			throw new ServiceException(e.getMessage());
		}
	}

	@Override
	public T modifier(T obj) throws ServiceException {
		try {
			U entity = getDao().modifier(mapper.map(obj, getEntityClass()));
			return mapper.map(entity, getEntityDtoClass());
		} catch (DaoException e) {
			throw new ServiceException(e.getMessage());
		}
	}

	@Override
	public void supprimer(T obj) throws ServiceException {
		try {
			getDao().supprimer(mapper.map(obj, getEntityClass()));
		} catch (DaoException e) {
			throw new ServiceException(e.getMessage());
		}

	}

	@Override
	public void supprimer(Collection<T> entities) throws ServiceException {
		try {
			List<U> listServer = new ArrayList<U>();
			for (T entity : entities) {
				listServer.add(mapper.map(entity, getEntityClass()));
			}
			getDao().supprimer(listServer);
		} catch (DaoException e) {
			throw new ServiceException(e.getMessage());
		}

	}

	@Override
	public Integer compter(ConfigRequetesDto config) throws ServiceException {
		try {
			ConfigRequetes configServer = transformConfigRequetes
					.transform(config);
			return getDao().compter(configServer);
		} catch (DaoException e) {
			throw new ServiceException(e.getMessage());
		}

	}

	@Override
	public List<T> trouver(ConfigRequetesDto config) throws ServiceException {
		try {
			List<T> listClient = new ArrayList<T>();

			ConfigRequetes configServer = transformConfigRequetes
					.transform(config);
			List<U> listServer = getDao().trouver(configServer);

			for (U entity : listServer) {
				listClient.add(mapper.map(entity, getEntityDtoClass()));
			}
			return listClient;
		} catch (DaoException e) {
			throw new ServiceException(e.getMessage());
		}

	}

}
